package net.wanderinghorse.json;

/**
 * A base implementation of the JSONable interface, implementing
 * all of the functions which do not require class-specific implementations.
 *
 * (This class exists so that JSONable can be an interface instead of a
 * class.)
 */
public abstract class AbstractJSONable implements JSONable {
    /**
     * Must return a JSON-compliant representation of this object,
     * in the form of a JSONObject.
     *
     * @return The JSONObject representation.
     * @throws JSONException if any of the underlying JSONObject members throws.
     *  Implementations may throw other unchecked exceptions.
     */
    public abstract JSONObject toJSONObject();

    /**
     * Equivalent to this.toJSONObject().toString().
     *
     * @return This object's JSON form.
     * @throws JSONException If the underlying JSONObject API throws.
     */
    public final String toJSON()
    {
        return this.toJSONObject().toString();
    }

    /**
     * Equivalent to this.toJSONObject().toString(indention).
     *
     * @param indention See JSONObject.toString(int).
     * @return This object's JSON form.
     * @throws JSONException If the underlying JSONObject API throws.
     */
    public final String toJSON(int indention)
    {
        return this.toJSONObject().toString(indention);
    }

    /**
     * Must populate this object from the given JSON source.
     *
     * @param src The source JSON data.
     * @throws JSONException If any JSONObject members throw. Implementations
     * may optionally throw if the input object violates the expected structure.
     */
    public abstract void fromJSONObject( final JSONObject src );

    /**
     * Equivalent to this.fromJSONObject( new JSONObject(src) ).
     *
     * @param src JSON string representation of this object.
     * @throws JSONException If any of the underlying JSONObject API throws.
     */
    public final void fromJSON( final String src )
    {
        this.fromJSONObject( new JSONObject(src) );
    }

    /**
     * Overridden to behave like toJSON(). If toJSON() throws then this
     * function returns null.
     * @return Equivalent to toJSON(), or null if that function throws.
     */
    @Override
    public String toString() {
        try {
            return this.toJSON();
        } catch(Exception e) {
            return null;
        }
    }
}
